package com.cqrt.aop;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqrt.config.CustomObjectMapper;
import com.cqrt.constant.RTErrorCodeEnum;
import com.cqrt.constant.RTPlmConstant;
import com.cqrt.entity.RTPrjTaskJobLinkDO;
import com.cqrt.mapper.RTOutRuleMapper;
import com.cqrt.mapper.RTProjectMapper;
import com.cqrt.mapper.RTProjectsTemplateMapper;
import com.cqrt.mapper.RTTaskMapper;
import com.cqrt.vo.OutRulesVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInfo;
import com.hustcad.plm.pdm.common.model.dto.search.SearchConditionDTO;
import com.hustcad.plm.pdm.common.model.dto.search.SearchTypeDTO;
import com.hustcad.plm.pdm.common.model.vo.search.ResultEntityVO;
import com.hustcad.plm.pdm.iba.mapper.TyplmAttributeValueMapper;
import com.hustcad.plm.pdm.iba.model.dto.SaveObjIBADTO;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.rpm.entityconvert.BaseConvert;
import com.hustcad.plm.rpm.model.dto.admin.TyppmProjectDTO;
import com.hustcad.plm.rpm.model.dto.job.JobRemoteDTO;
import com.hustcad.plm.rpm.model.dto.job.JobStatusUpdateDTO;
import com.hustcad.plm.rpm.model.dto.job.TyppmJobDTO;
import com.hustcad.plm.rpm.model.dto.outrule.TyppmOutRuleDTO;
import com.hustcad.plm.rpm.model.dto.remote.BatchInsertDocVO;
import com.hustcad.plm.rpm.model.dto.remote.DocDetailsVO;
import com.hustcad.plm.rpm.model.dto.remote.RemoteObjDTO;
import com.hustcad.plm.rpm.model.vo.outrule.OutRuleItemVO;
import com.hustcad.plm.rpm.model.vo.outrule.OutRuleParamVO;
import com.hustcad.plm.rpm.model.vo.project.OutRuleVO;
import com.hustcad.plm.rpm.model.vo.recent.TyppmOperationRecordVO;
import com.hustcad.plm.rpm.service.job.TyppmJobService;
import com.hustcad.plm.rpm.service.outrule.TyppmOutRuleService;
import com.hustcad.plm.rpm.service.remote.TyppmRemotePdmService;
import com.hustcad.plm.rpm.util.request.RequestBase;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.dto.constraint.IbaDTO;
import com.ty.basic.entity.CTyEntityBaseDO;
import com.ty.basic.entity.attribute.StringValueDO;
import com.ty.basic.response.ResponseResult;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import com.ty.basic.vo.AttributeVO;
import com.ty.ppm.model.entity.job.Job;
import com.ty.ppm.model.utils.Tools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DeadlockLoserDataAccessException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import javax.swing.text.Utilities;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Aspect
@Component
@Slf4j
@Transactional
public class OutRuleAop {

    @Resource
    private TyppmOutRuleService typpmOutRuleService;
    @Resource
    private RTOutRuleMapper rtOutRuleMapper;;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private RTProjectMapper rtProjectMapper;
    @Resource
    private RTTaskMapper rtTaskMapper;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private TyppmRemotePdmService typpmRemotePdmService;
    @Resource
    private TyppmJobService typpmJobService;

    @Resource
    private TyplmAttributeValueMapper typlmAttributeValueMapper;

    @Resource
    private RTProjectsTemplateMapper rtProjectsTemplateMapper;
    @Resource
    private BaseConvert baseConvert;


    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;

    @Value("${rule.condition.key}")
    private String ruleConditionKey;
    @Value("${query.url}")
    private String queryConditionUrl;

    @Around("execution(* com.hustcad.plm.rpm.service.job.TyppmJobService.setSubmitState(..))")
    public Object aroundControllerMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        JobStatusUpdateDTO job = (JobStatusUpdateDTO) joinPoint.getArgs()[0];
        RTPrjTaskJobLinkDO taskJobLinkDO=rtTaskMapper.existTemporaryTask(job.getJobId());
        //----------------------------------------------------------------------------------------
       for (int i=0;i<1;i++){
           BigInteger parentID = rtTaskMapper.selectParentById(job.getJobId());
           if (ObjectUtil.isNull(parentID)) {
               break;
           }

           Map<String, List<AttributeVO>> ibaMaps = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                   Collections.singletonList(new BigInteger(job.getJobId())),
                   TableTypeConstrant.TY_JOB_OTYPE,
                   Collections.singletonList("ParentTask"));
           if (CollUtil.isEmpty(ibaMaps)){
               break;
           }
           List<String> attrValueList = ibaMaps.values().stream()
                   .flatMap(List::stream)
                   .map(AttributeVO::getAttributeValue)
                   .filter(attributeValue -> StringUtils.isNotEmpty(String.valueOf(attributeValue)))
                   .distinct()
                   .collect(Collectors.toList());

           if (CollUtil.isEmpty(attrValueList) || !StringUtils.equalsIgnoreCase(attrValueList.get(0), "true")){
               break;
           }

           //同步交付物
           BigInteger prj1=rtTaskMapper.selectPrjByID(job.getJobId());
           PageInfo<TyppmOutRuleDTO> curRuleList1 = typpmOutRuleService.queryOutRuleByPage(job.getJobId(), null, null, null);
           PageInfo<TyppmOutRuleDTO> parRuleList1 = typpmOutRuleService.queryOutRuleByPage(parentID.toString(), null, null, null);
           List<TyppmOutRuleDTO> commonRuleList1 = findCommonByNames(parRuleList1, curRuleList1);
           List<TyppmOutRuleDTO> oldCommonRuleList1 = findCommonByNames(curRuleList1, parRuleList1);
           for (TyppmOutRuleDTO typpmOutRuleDTO : commonRuleList1) {
               if (CollUtil.isEmpty(typpmOutRuleDTO.getDeliverName())){
                   continue;
               }
               for (RemoteObjDTO remoteObjDTO : typpmOutRuleDTO.getDeliverName()) {
                   //通过类型关联参考对象
                   SearchTypeDTO searchTypeDTO=rtTaskMapper.selectTypeByName(typpmOutRuleDTO.getRuletypeDisplayName());
                   SearchConditionDTO conditionDTO=new SearchConditionDTO();
                   conditionDTO.setConditionJoint("and");
                   conditionDTO.setKeyword(remoteObjDTO.getCode());
                   conditionDTO.setNeedCount(false);
                   conditionDTO.setPageNum(1);
                   conditionDTO.setPageSize(20);
                   conditionDTO.setTypeList(Collections.singletonList(searchTypeDTO));

                   HttpHeaders headers = new HttpHeaders();
                   headers.set(HttpHeaders.AUTHORIZATION, TyAccountContext.getToken());
                   headers.set(HttpHeaders.CONTENT_TYPE, "application/json");
                   HttpEntity<SearchConditionDTO> requestEntity = new HttpEntity<>(conditionDTO, headers);
                   ResponseEntity<String> responseEntity = restTemplate.exchange(
                           queryConditionUrl,
                           HttpMethod.POST,
                           requestEntity,
                           String.class
                   );
                   if (responseEntity.getStatusCode().is2xxSuccessful()) {
                       String jsonBody = responseEntity.getBody();
                       ObjectMapper objectMapper = new CustomObjectMapper(); // 应用日期解析规则
                       try {
                           ResponseResult<PageInfo<ResultEntityVO>> responseResult = objectMapper.readValue(
                                   jsonBody,
                                   new TypeReference<ResponseResult<PageInfo<ResultEntityVO>>>() {}
                           );
                           if (ObjectUtil.isNotNull(responseResult)) {
                               // 返回分页数据
                               List<ResultEntityVO> remoteObjList = responseResult.getData().getList();
                               List<ResultEntityVO> filteredList = remoteObjList.stream()
                                       .filter(vo -> Objects.equals(vo.getObjectNumber(), remoteObjDTO.getCode()))
                                       .collect(Collectors.toList());
                               if (CollUtil.isEmpty(filteredList) || filteredList.size() != 1) {
                                   throw RTErrorCodeEnum.TYPEOBJ_NOT_EXIST.getException("该类型对象不存在或编码重复");
                               }
                               BatchInsertDocVO batchInsetDocVO = new BatchInsertDocVO();
                               batchInsetDocVO.setDocOtype(typpmOutRuleDTO.getParentOtype());
                               batchInsetDocVO.setLocalRepositoryUid("javaPDM");
                               batchInsetDocVO.setOutputRuleOid(getFirstOidByName(oldCommonRuleList1,typpmOutRuleDTO.getName()));
                               batchInsetDocVO.setParentNodeOid(parentID.toString());
                               batchInsetDocVO.setParentNodeOtype(TableTypeConstrant.TY_JOB_OTYPE);
                               batchInsetDocVO.setProjectOid(prj1.toString());
                               batchInsetDocVO.setType("OUT");
                               List<DocDetailsVO> docDetailsVOS = BeanUtil.copyToList(filteredList, DocDetailsVO.class);
                               batchInsetDocVO.setDocList(docDetailsVOS);
                               this.typpmRemotePdmService.insertRemoteDoc(batchInsetDocVO);
                           } else {
                               assert responseResult != null;
                               throw new RuntimeException("接口返回异常：" + responseResult.getMessage());
                           }
                       } catch (JsonProcessingException e) {
                           throw new RuntimeException(e);
                       }
                   }
               }
           }

//           //2.获取父任务下的所有子任务的状态是否为已提交
//           List<Job> jobList = rtTaskMapper.selectAllJobByParentID(parentID);
//           boolean allSubmitted = jobList.stream()
//                   .map(Job::getState)           // 提取每个子任务的状态
//                   .allMatch("已提交"::equals);
//           if (!allSubmitted){
//               break;
//           }
//
//           //3.父任务自动提交
//           RequestBase<JobStatusUpdateDTO> requestBase=new RequestBase<>();
//           JobStatusUpdateDTO jobStatusUpdateDTO = new JobStatusUpdateDTO();
//           jobStatusUpdateDTO.setJobId(parentID.toString());
//           TyppmOperationRecordVO operationRecordVO=new TyppmOperationRecordVO();
//           operationRecordVO.setPassname("提交");
//           operationRecordVO.setRemark("1");
//           jobStatusUpdateDTO.setOperationRecordVO(operationRecordVO);
//           requestBase.setInput(jobStatusUpdateDTO);
//           typpmJobService.setSubmitState(requestBase.getInput(), "已提交");
       }
        //----------------------    ------------------------------------------------------------------


        //1.判断当前是否是临时任务
        if (ObjectUtil.isNull(taskJobLinkDO)){
            bindAndSaveSingleIbaAttribute(new BigInteger(job.getJobId()), TableTypeConstrant.TY_JOB_OTYPE, ruleConditionKey, "通过");
            return joinPoint.proceed();
        }

        //2.交付物回传原任务
        BigInteger prj=rtTaskMapper.selectPrjByID(taskJobLinkDO.getJoboid().toString());
        PageInfo<TyppmOutRuleDTO> curRuleList = typpmOutRuleService.queryOutRuleByPage(job.getJobId(), null, null, null);
        PageInfo<TyppmOutRuleDTO> parRuleList = typpmOutRuleService.queryOutRuleByPage(taskJobLinkDO.getJoboid().toString(), null, null, null);
        List<TyppmOutRuleDTO> commonRuleList = findCommonByNames(parRuleList, curRuleList);
        List<TyppmOutRuleDTO> oldCommonRuleList = findCommonByNames(curRuleList, parRuleList);
        for (TyppmOutRuleDTO typpmOutRuleDTO : commonRuleList) {
            if (CollUtil.isEmpty(typpmOutRuleDTO.getDeliverName())){
                continue;
            }
            for (RemoteObjDTO remoteObjDTO : typpmOutRuleDTO.getDeliverName()) {
                //通过类型关联参考对象
                SearchTypeDTO searchTypeDTO=rtTaskMapper.selectTypeByName(typpmOutRuleDTO.getRuletypeDisplayName());
                SearchConditionDTO conditionDTO=new SearchConditionDTO();
                conditionDTO.setConditionJoint("and");
                conditionDTO.setKeyword(remoteObjDTO.getCode());
                conditionDTO.setNeedCount(false);
                conditionDTO.setPageNum(1);
                conditionDTO.setPageSize(20);
                conditionDTO.setTypeList(Collections.singletonList(searchTypeDTO));

                HttpHeaders headers = new HttpHeaders();
                headers.set(HttpHeaders.AUTHORIZATION, TyAccountContext.getToken());
                headers.set(HttpHeaders.CONTENT_TYPE, "application/json");
                HttpEntity<SearchConditionDTO> requestEntity = new HttpEntity<>(conditionDTO, headers);
                ResponseEntity<String> responseEntity = restTemplate.exchange(
                        queryConditionUrl,
                        HttpMethod.POST,
                        requestEntity,
                        String.class
                );
                if (responseEntity.getStatusCode().is2xxSuccessful()) {
                    String jsonBody = responseEntity.getBody();
                    ObjectMapper objectMapper = new CustomObjectMapper(); // 应用日期解析规则
                    try {
                        ResponseResult<PageInfo<ResultEntityVO>> responseResult = objectMapper.readValue(
                                jsonBody,
                                new TypeReference<ResponseResult<PageInfo<ResultEntityVO>>>() {}
                        );
                        if (ObjectUtil.isNotNull(responseResult)) {
                            // 返回分页数据
                            List<ResultEntityVO> remoteObjList = responseResult.getData().getList();
                            List<ResultEntityVO> filteredList = remoteObjList.stream()
                                    .filter(vo -> Objects.equals(vo.getObjectNumber(), remoteObjDTO.getCode()))
                                    .collect(Collectors.toList());
                            if (CollUtil.isEmpty(filteredList) || filteredList.size() != 1) {
                                throw RTErrorCodeEnum.TYPEOBJ_NOT_EXIST.getException("该类型对象不存在或编码重复");
                            }
                            BatchInsertDocVO batchInsetDocVO = new BatchInsertDocVO();
                            batchInsetDocVO.setDocOtype(typpmOutRuleDTO.getParentOtype());
                            batchInsetDocVO.setLocalRepositoryUid("javaPDM");
                            batchInsetDocVO.setOutputRuleOid(getFirstOidByName(oldCommonRuleList,typpmOutRuleDTO.getName()));
                            batchInsetDocVO.setParentNodeOid(taskJobLinkDO.getJoboid().toString());
                            batchInsetDocVO.setParentNodeOtype(TableTypeConstrant.TY_JOB_OTYPE);
                            batchInsetDocVO.setProjectOid(prj.toString());
                            batchInsetDocVO.setType("OUT");
                            List<DocDetailsVO> docDetailsVOS = BeanUtil.copyToList(filteredList, DocDetailsVO.class);
                            batchInsetDocVO.setDocList(docDetailsVOS);
                            this.typpmRemotePdmService.insertRemoteDoc(batchInsetDocVO);
                        } else {
                            assert responseResult != null;
                            throw new RuntimeException("接口返回异常：" + responseResult.getMessage());
                        }
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

       // 3.修改属性值
        rtTaskMapper.updateTaskState(taskJobLinkDO.getTaskoid());
//       Integer count= rtTaskMapper.countIssubmit(taskJobLinkDO.getTaskoid());
//       if (ObjectUtil.isNull(count)){
//           bindAndSaveSingleIbaAttribute(taskJobLinkDO.getJoboid(), TableTypeConstrant.TY_PLAN_OTYPE, ruleConditionKey, "passThrough");
//       }

        return joinPoint.proceed();
    }

    private String getFirstOidByName(List<TyppmOutRuleDTO> ruleList, String targetName) {
        if (ruleList == null || targetName == null) {
            return null;
        }
        return ruleList.stream()
                .filter(rule -> targetName.equals(rule.getName()))
                .map(TyppmOutRuleDTO::getOid)
                .findFirst()
                .orElse(null);
    }

    private List<TyppmOutRuleDTO> findCommonByNames(
            PageInfo<TyppmOutRuleDTO> page1,
            PageInfo<TyppmOutRuleDTO> page2) {
        Set<String> namesFromFirstList = page1.getList().stream()
                .map(TyppmOutRuleDTO::getName)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        return page2.getList().stream()
                .filter(dto -> {
                    String name = dto.getName();
                    return name != null && namesFromFirstList.contains(name);
                })
                .collect(Collectors.toList());
    }


    /**
     * 更新任务的条件通过属性
     */
    private void updateJobConditionApproval(BigInteger jobId, String newValue) {
         bindAndSaveSingleIbaAttribute(jobId, TableTypeConstrant.TY_JOB_OTYPE, ruleConditionKey, newValue);
    }


    private String determineConditionApproval(List<TyppmOutRuleDTO> delayedRules) {
        // 如果存在"立即提交=否"的规则，设置为"条件通过"
        if (CollUtil.isNotEmpty(delayedRules)) {
            return "conditionPassed";
        }
        // 否则设置为"通过"
        return "passThrough";
    }


    private boolean existSalveJob(String jobId) {
        return rtProjectMapper.existSalveJob(jobId);
    }



    private List<TyppmOutRuleDTO> processRuleAttributes(List<TyppmOutRuleDTO> ruleList) {
        List<TyppmOutRuleDTO> delayedRules = new ArrayList<>();
        for (TyppmOutRuleDTO rule : ruleList) {
            Map<String, String> ruleAttributes = parseRuleAttributes(rule.getRuleDisplayName());
            // 检查"是否必须"属性
            if (ruleAttributes.containsKey(RTPlmConstant.REQUIRED) &&
                    RTPlmConstant.OK.equals(ruleAttributes.get(RTPlmConstant.REQUIRED))) {

                if (CollectionUtil.isEmpty(rule.getDeliverName())) {
                    throw RTErrorCodeEnum.REMOTEOBJ_NOT_EXIST.getException(
                            "该规则下交付物不能为空，请添加交付物!");
                }
            }
            // 处理"立即提交"属性（如果为否，软删除交付物）
            if (ruleAttributes.containsKey(RTPlmConstant.SUBMIT) &&
                    RTPlmConstant.NO.equals(ruleAttributes.get(RTPlmConstant.SUBMIT))) {
                if(CollUtil.isEmpty(rule.getDeliverName())){
                    delayedRules.add(rule);
                }
            }
            // 检查"任一提交"属性
            if (ruleAttributes.containsKey(RTPlmConstant.ANYSUBMISSION) &&
                    RTPlmConstant.OK.equals(ruleAttributes.get(RTPlmConstant.ANYSUBMISSION))) {
                List<BigInteger> typeOid = rtOutRuleMapper.selectAllTypeById(rule.getRuletypeOid());
                long count = ruleList.stream()
                        .filter(r -> typeOid.contains(new BigInteger(r.getRuletypeOid())))
                        .filter(r -> {
                            Map<String, String> attrs = parseRuleAttributes(r.getRuleDisplayName());
                            return attrs.containsKey(RTPlmConstant.ANYSUBMISSION) &&
                                    RTPlmConstant.OK.equals(attrs.get(RTPlmConstant.ANYSUBMISSION));
                        })
                        .count();
                if (count < 2) {
                    throw RTErrorCodeEnum.ANYSUBMISSION_UNIQUE_ERROR.getException("任一提交单独设置不生效");
                }
            }
        }

        return delayedRules;
    }


    public void bindAndSaveSingleIbaAttribute(BigInteger objOid, String objOtype, String attrKey, String attrValue) {
        // 1. 校验入参有效性
        if (objOid == null || StringUtils.isBlank(objOtype)
                || StringUtils.isBlank(attrKey) || StringUtils.isBlank(attrValue)) {
            log.warn("绑定IBA属性失败：参数不能为空，objOid={}, objOtype={}, attrKey={}",
                     objOid, objOtype, attrKey);
        }
        // 2. 创建IBA属性DTO
        IbaDTO ibaDTO = new IbaDTO();
        ibaDTO.setKey(attrKey);
        ibaDTO.setValue(attrValue);
        // 3. 创建"对象+属性"绑定DTO
        SaveObjIBADTO saveDTO = new SaveObjIBADTO();
        saveDTO.setObjIbaList(Collections.singletonList(ibaDTO));

        // 4. 设置对象基础信息
        saveDTO.setCTyEntityBaseDO(new CTyEntityBaseDO(objOid, objOtype));

        // 5. 批量保存（单对象）
        try {
            typlmAttributeValueService.batchSaveIBAByObjList(Collections.singletonList(saveDTO), false);
        } catch (Exception e) {
            log.error("绑定IBA属性失败，objOid={}, attrKey={}", objOid, attrKey, e);
        }
    }


    /**
     * 解析规则显示名称中的属性
     * @param ruleDisplayName
     * @return
     */
    public Map<String, String> parseRuleAttributes(String ruleDisplayName) {
        Map<String, String> attributes = new HashMap<>();
        if (ruleDisplayName == null || ruleDisplayName.isEmpty()) {
            return attributes;
        }
        String[] pairs = ruleDisplayName.split(";");
        for (String pair : pairs) {
            int colonIndex = pair.indexOf(':');
            if (colonIndex > 0 && colonIndex < pair.length() - 1) {
                String key = pair.substring(0, colonIndex).trim();
                String value = pair.substring(colonIndex + 1).trim();
                attributes.put(key, value);
            }
        }
        return attributes;
    }


    //修改任务提交状态为已完成
    /*@AfterReturning("execution(* com.hustcad.plm.rpm.service.job.TyppmJobService.setSubmitState(..))")
    public void changeJobSubmitState(JoinPoint jp) throws Throwable {
        JobStatusUpdateDTO jobStatusUpdateDTO = (JobStatusUpdateDTO) jp.getArgs()[0];
        String jobId = jobStatusUpdateDTO.getJobId();
        if (ObjectUtil.isNotNull(jobId)){
            rtTaskMapper.changeJobSubmitState(jobId);
        }

    }*/
    //提交交付物时，更新通过状态为通过

    @Before("execution(* com.hustcad.plm.rpm.service.impl.remote.TyppmRemotePdmServiceImpl.insertRemoteDoc(..))")
    public void throughPassStatus(JoinPoint jp) throws Throwable {

        //取得插入参数
        BatchInsertDocVO batchInsertDocVO = (BatchInsertDocVO) jp.getArgs()[0];
        String outputRuleOid = batchInsertDocVO.getOutputRuleOid();
        BigInteger jobOid = rtOutRuleMapper.selectJobOidByOutRuleOid(outputRuleOid);
        String jobOId = "";
        if (jobOid != null) {
             jobOId = jobOid.toString();
        }

        //更新父任务的交付物状态
//        String parentNodeOid = batchInsertDocVO.getParentNodeOid();
//        BigInteger grandParentNodeOid = rtOutRuleMapper.selectJobOidBySubJobOid(parentNodeOid);
//        String outRuleName = rtOutRuleMapper.selectNameByOutRuleOid(outputRuleOid);
//        BigInteger parentOutRuleOid = rtOutRuleMapper.selectOutRuleOidByJobOidAndName(parentNodeOid, outRuleName);
//        //提交父类的交付物
//        if (parentOutRuleOid != null&&grandParentNodeOid!=null){
//            batchInsertDocVO.setParentNodeOid(grandParentNodeOid.toString());
//            batchInsertDocVO.setOutputRuleOid(parentOutRuleOid.toString());
//            this.typpmRemotePdmService.insertRemoteDoc(batchInsertDocVO);
//        }
//        //再给改回来
//        batchInsertDocVO.setParentNodeOid(parentNodeOid);
//        batchInsertDocVO.setOutputRuleOid(outputRuleOid);
        //提交交付物时，更新通过状态为通过
        //设置一个列表接收数据
        if(BeanUtil.isNotEmpty(jobOid)||BeanUtil.isNotEmpty(outputRuleOid)) {
            List<StringValueDO> stringValueDOList = new ArrayList<>();
            //转换为BigInteger类型，并给StringValueDO赋值
            BigInteger oid = snowflakeIdComponent.getInstance().nextId();
            StringValueDO stringValueDO = new StringValueDO();
            stringValueDO.setObjbaseoid(jobOid);
            stringValueDO.setObjbaseotype("ty.projectmng.job.CTyJob");
            BigInteger throughStatus = rtOutRuleMapper.selectOidByDisplayName("通过状态");
            stringValueDO.setAttrdefoid(throughStatus);
            stringValueDO.setAttrdefotype("ty.inteplm.attribute.CTyStringDef");
            stringValueDO.setCreatestamp(new Date());
            stringValueDO.setUpdatestamp(new Date());
            stringValueDO.setModifystamp(new Date());
            stringValueDO.setRefobjbaseotype("ty.zddw.kernel.CTyReferenceBase");
            stringValueDO.setOid(oid);

            stringValueDO.setValue("通过");
            stringValueDO.setValuex("通过");
            //添加进列表
            stringValueDOList.add(stringValueDO);
            //更新任务通过状态
            updateJobThroughStatus(stringValueDOList, jobOId);

        }



    }

//    //进入项目计划页面时，更新交付物通过状态
//    @Transactional
//    @AfterReturning(pointcut = "execution(* com.hustcad.plm.rpm.service.plan.TyppmPlanActiveService.queryPlanActiveTreeByRootOIDAndRootOTYPE(..))"
//            , returning = "result")
//    public Object updatePlanPassStatus(Object result) throws Throwable {
//        JSONObject tree = (JSONObject) result;
//        JSONArray tasks = tree.getJSONArray("Tasks");
//        List<String> jobOidList = new ArrayList<>();
//        JSONArray children = new JSONArray();
//        for (Object item : tasks) {
//            if(item instanceof JSONObject){
//                JSONObject jsonObject = (JSONObject) item;
//                if(jsonObject.getString("id")!=null&&jsonObject.getString("id")!=""){
//                    String id = jsonObject.getString("id");
//                    List<BigInteger> newJobOid = rtOutRuleMapper.selectJobOidByActivityId(id);
//                    if(CollUtil.isNotEmpty(newJobOid)){
//                        String newJobOId = newJobOid.get(0).toString();
//                        jobOidList.add(newJobOId);
//                    }
//                }
//            }
//            traverseElement(item, children);
//        }
//
//        for (int i = 0; i < children.size(); i++) {
//
//
//            try {
//                JSONArray jsonArray = children.getJSONArray(i);
//                for (int j = 0; j < jsonArray.size(); j++) {
//                    JSONObject jsonObject = jsonArray.getJSONObject(j);
//                    if (jsonObject != null) {
//                        String id = jsonObject.getString("id");
//                        if (id != null && !id.isEmpty()) {
//                            List<BigInteger> newJobOid = rtOutRuleMapper.selectJobOidByActivityId(id);
//                            if(CollUtil.isNotEmpty(newJobOid)){
//                                String newJobOId = newJobOid.get(0).toString();
//                                jobOidList.add(newJobOId);
//                            }
//                        }
//
//                    }
//
//                }
//
//            } catch (Exception e) {
//                // 处理可能的异常，避免程序中断
//                log.warn("获取 jobOid 时发生异常: {}", e.getMessage());
//            }
//
//
//        }
//for (String jobOid : jobOidList){
//    typpmOutRuleService.queryOutRuleByPage(jobOid, "", 1, 20);
//}
//
//        return result;
//    }
    /**
     * 递归遍历JSON元素（可能是JSONObject、JSONArray或基本类型）
     * @param element 当前处理的元素
     * @param resultList 存储结果的列表
     */
    private static void traverseElement(Object element, List<Object> resultList) {
        if (element == null) {
            return;
        }

        // 处理JSONObject类型的元素
        if (element instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) element;
            Set<String> keys = jsonObj.keySet();

            // 检查当前对象是否包含"children"键
            if (keys.contains("children")&&jsonObj.get("children")!=null) {
                resultList.add(jsonObj.get("children"));
            }

            // 递归遍历当前对象的所有值，处理嵌套结构
            for (String key : keys) {
                Object value = jsonObj.get(key);
                traverseElement(value, resultList);
            }
        }
        // 处理JSONArray类型的元素
        else if (element instanceof JSONArray) {
            JSONArray jsonArray = (JSONArray) element;
            // 遍历数组中的每个元素并递归处理
            for (Object item : jsonArray) {
                traverseElement(item, resultList);
            }
        }
        // 基本类型（字符串、数字等）不做处理
    }

    //填写交付规则时，更新通过状态

    @Before("execution(* com.hustcad.plm.rpm.service.impl.outrule.TyppmOutRuleServiceImpl.insertOutRule(..))")
    public void updatePassStatus(JoinPoint jp) throws Throwable {

        //取得插入参数
        OutRuleParamVO jobStatusUpdateDTO = (OutRuleParamVO) jp.getArgs()[0];
        List<OutRuleItemVO> outRuleItemList = jobStatusUpdateDTO.getOutRuleItemList();
        //设置一个列表接收数据
        List<StringValueDO> stringValueDOList = new ArrayList<>();

        PageInfo<TyppmOutRuleDTO> typpmOutRuleDTOPageInfo = this.typpmOutRuleService.queryOutRuleByPage(jobStatusUpdateDTO.getOutRule().getJobOid(), null, 1,
                                                                                                        9999);
        for (TyppmOutRuleDTO typpmOutRuleDTO : typpmOutRuleDTOPageInfo.getList()) {
            if (typpmOutRuleDTO.getRuletypeOid().equals(jobStatusUpdateDTO.getOutRule().getRuletypeOid())){
                throw  RTErrorCodeEnum.REPETITIVE_TYPE.getException("重复的交付类型");
            }
        }
        //判断非空
        if (CollUtil.isNotEmpty(outRuleItemList)) {
            //循环遍历交付物条件
            for (OutRuleItemVO outRuleItemVO : outRuleItemList) {
                //为立即提交
                List<BigInteger> submitNowList = rtOutRuleMapper.selectOidByName("立即提交");
                boolean isSubmitNow = false;
                for (BigInteger submitNow : submitNowList) {
                    if (submitNow.equals(new BigInteger(outRuleItemVO.getAttributeOid()))) {
                        isSubmitNow = true;
                        break;
                    }
                }
                if (outRuleItemVO.getAttributeOid() != null && isSubmitNow == true) {
                    //转换为BigInteger类型，并给StringValueDO赋值
                    BigInteger oid = snowflakeIdComponent.getInstance().nextId();
                    String jobOid = "";
                    jobOid = jobStatusUpdateDTO.getOutRule().getJobOid();
                    BigInteger jobOId = new BigInteger(jobOid);
                    StringValueDO stringValueDO = new StringValueDO();
                    stringValueDO.setObjbaseoid(jobOId);
                    stringValueDO.setObjbaseotype("ty.projectmng.job.CTyJob");
                    BigInteger throughStatus = rtOutRuleMapper.selectOidByDisplayName("通过状态");
                    stringValueDO.setAttrdefoid(throughStatus);
                    stringValueDO.setAttrdefotype("ty.inteplm.attribute.CTyStringDef");
                    stringValueDO.setCreatestamp(new Date());
                    stringValueDO.setUpdatestamp(new Date());
                    stringValueDO.setModifystamp(new Date());
                    stringValueDO.setRefobjbaseotype("ty.zddw.kernel.CTyReferenceBase");
                    stringValueDO.setOid(oid);
                    //为否
                    List<BigInteger> no = rtOutRuleMapper.selectOidByNameEnum("NO");
                    no.addAll(rtOutRuleMapper.selectOidByNameEnum("no"));
                    boolean isNO = false;
                    for (BigInteger ifNO : no) {
                        if (ifNO.equals(new BigInteger(outRuleItemVO.getAttributeValueOid()))) {
                            isNO = true;
                            break;
                        }
                    }

                    if (outRuleItemVO.getAttributeValueOid() != null && isNO) {
                        stringValueDO.setValue("条件通过");
                        stringValueDO.setValuex("条件通过");
                        //添加进列表

                    }
                    //为是
                    List<BigInteger> ok = rtOutRuleMapper.selectOidByNameEnum("OK");
                     ok.addAll(rtOutRuleMapper.selectOidByNameEnum("ok"));
                    boolean isOK = false;
                    for (BigInteger ifOK : ok) {
                        if (ifOK.equals(new BigInteger(outRuleItemVO.getAttributeValueOid()))) {
                            isOK = true;
                            break;
                        }
                    }
                    if (outRuleItemVO.getAttributeValueOid() != null && isOK) {
         //               stringValueDO.setValue("通过");
          //              stringValueDO.setValuex("通过");
                        //添加进列表
                    }
                    stringValueDOList.add(stringValueDO);


                }
            }
            updateJobThroughStatus(stringValueDOList, jobStatusUpdateDTO.getOutRule().getJobOid());
        }

    }

//    //模板导入时刷新通过状态
//
//    @AfterReturning(pointcut = "execution(* com.hustcad.plm.rpm.service.impl.outrule.TyppmOutRuleServiceImpl.queryOutRuleByPage(..))",
//            returning = "result")
//    public Object changeTemplatePassStatus(Object result) throws Throwable {
//        PageInfo<TyppmOutRuleDTO> pageInfo = (PageInfo<TyppmOutRuleDTO>) result;
//
//
//return result;
//    }

    //向页面返回交付物规则是否绑定模板以及是否完成
    @Around("execution(* com.hustcad.plm.rpm.service.impl.outrule.TyppmOutRuleServiceImpl.queryOutRuleByPage(..))")
    public Object updateOutRulePassStatus(ProceedingJoinPoint point) throws Throwable {
        PageInfo<TyppmOutRuleDTO> proceed = (PageInfo<TyppmOutRuleDTO>) point.proceed();

        List<TyppmOutRuleDTO> outRuleDTOList = proceed.getList();

        //设置一个列表接收数据
        List<StringValueDO> stringValueDOList = new ArrayList<>();

        //判断非空
        if (CollUtil.isNotEmpty(outRuleDTOList)) {

            String checkJobOid = "";
            //循环遍历交付物条件
            for (TyppmOutRuleDTO outRuleDTO : outRuleDTOList) {
                String name = "";
                name = outRuleDTO.getRuleDisplayName();
                if (ObjectUtil.isNotEmpty(name)) {
                    String[] stringBeforeHyphen = getStringBeforeHyphen(name);
                    String[] stringBeforeColon = getStringBeforeColon(stringBeforeHyphen);
                    boolean isSubmitNow = false;
                    for (String s : stringBeforeColon) {
                        if (s.equals("立即提交")) {
                            isSubmitNow = true;
                            break;
                        }

                    }

                    //如果不是同一个的任务，不为空，并且是立即提交
                    if (!checkJobOid.equals(outRuleDTO.getJobOid()) && outRuleDTO.getName() != null && isSubmitNow) {
                        //转换为BigInteger类型，并给StringValueDO赋值
                        BigInteger oid = snowflakeIdComponent.getInstance().nextId();
                        String jobOid = "";
                        jobOid = outRuleDTO.getJobOid();
                        BigInteger jobOId = new BigInteger(jobOid);
                        StringValueDO stringValueDO = new StringValueDO();
                        stringValueDO.setObjbaseoid(jobOId);
                        stringValueDO.setObjbaseotype("ty.projectmng.job.CTyJob");
                        BigInteger throughStatus = rtOutRuleMapper.selectOidByDisplayName("通过状态");
                        stringValueDO.setAttrdefoid(throughStatus);
                        stringValueDO.setAttrdefotype("ty.inteplm.attribute.CTyStringDef");
                        stringValueDO.setCreatestamp(new Date());
                        stringValueDO.setUpdatestamp(new Date());
                        stringValueDO.setModifystamp(new Date());
                        stringValueDO.setRefobjbaseotype("ty.zddw.kernel.CTyReferenceBase");
                        stringValueDO.setOid(oid);


                        if (rtOutRuleMapper.selectIsHasDeliverObj(outRuleDTO.getOid()).isEmpty()) {

                            String[] beforeHyphen = getStringBeforeHyphen(outRuleDTO.getRuleDisplayName());
                            for (String s : beforeHyphen) {
                                if (s.equals("立即提交:否")) {
                                    stringValueDO.setValue("条件通过");
                                    stringValueDO.setValuex("条件通过");
                                    //添加进列表

                                } else if (s.equals("立即提交:是")) {
                                    //stringValueDO.setValue("通过");
                                    //stringValueDO.setValuex("通过");
                                    //添加进列表
                                }
                            }


                        } else {
                          //  stringValueDO.setValue("通过");
                          //  stringValueDO.setValuex("通过");
                        }
                        //记录下当前的jobOid
                        checkJobOid = jobOid;
                        stringValueDOList.add(stringValueDO);
                    }
                }
            }
            updateJobThroughStatus(stringValueDOList, outRuleDTOList.get(0).getJobOid());
        }
        PageInfo<OutRuleVO> pageInfo = new PageInfo<>(proceed.getList().stream().map(item -> {
            OutRuleVO outRuleVO = new OutRuleVO();
            BeanUtils.copyProperties(item, outRuleVO);
            return outRuleVO;
        }).collect(Collectors.toList()));
        String jobOid = (String) point.getArgs()[0];
        if (proceed != null) {

            //通过任务oid查询计划oid
            BigInteger planOidBigInteger = rtProjectMapper.selectPlanOidByOid(jobOid);
            if (planOidBigInteger == null) {
                return pageInfo;
            }
            String planOid = "";
            if (planOidBigInteger != null) {
                planOid = planOidBigInteger.toString();
            }
            //通过计划oid查询计划模板oid
            List<BigInteger> templateOid = rtProjectsTemplateMapper.selectTemplateValueByOId(planOid);


            //    if (ObjectUtil.isNotEmpty(templateOid)) {
            pageInfo.getList().forEach(item -> {
                if (ObjectUtil.isNotEmpty(rtOutRuleMapper.selectOutRuleIsNew(item.getOid()))) {
                    item.setTemplate(true);
                }
            });
            //   }
            //判断交付物规则是否绑定交付物

            pageInfo.getList().forEach(item -> {
                String outRuleOid = item.getOid();
                //根据交付物规则Oid查询对应的交付物Oid
                List<BigInteger> deliverOidList = rtOutRuleMapper.selectDeliverOidByOutRuleOid(outRuleOid);
                if (ObjectUtil.isNotEmpty(deliverOidList)) {
                    item.setStatus("已完成");
                }
            });


        }
        return pageInfo;
    }
//更改类型的中文返回值
    @Around("execution(* com.hustcad.plm.rpm.service.outrule.TyppmOutRuleService.queryOutRule(..))")
    public Object updateDisplayName(ProceedingJoinPoint point) throws Throwable {
        OutRuleParamVO outRuleParamVO = (OutRuleParamVO) point.proceed();
        com.hustcad.plm.rpm.model.vo.outrule.OutRuleVO outRule = outRuleParamVO.getOutRule();
        String ruleTypeName = outRule.getRuleTypeName();
        OutRulesVO outRulesVO = new OutRulesVO();
        BeanUtils.copyProperties(outRule, outRulesVO);
        if (ruleTypeName != null&&ruleTypeName!="") {
            outRulesVO.setEnglishName(ruleTypeName);
            String chineseName = "";
                    chineseName = rtOutRuleMapper.selectRuleTypeDisplayName(ruleTypeName);
                    if (chineseName != null&&chineseName!="") {
                        outRulesVO.setRuleTypeName(chineseName);
                    }
        }
outRuleParamVO.setOutRule(outRulesVO);
        return outRuleParamVO;
    }
//临时任务刷条件通过
    @Around("execution(* com.hustcad.plm.rpm.service.job.TyppmJobService.batchCreateJobListByParentJob(..))")
    public Object updateTemporaryTask(ProceedingJoinPoint point) throws Throwable {
        List<TyppmJobDTO> jobDTOList = (List<TyppmJobDTO>) point.proceed();
        for (TyppmJobDTO jobDTO : jobDTOList){
            List<StringValueDO> stringValueDOList = new ArrayList<>();
            BigInteger oid = snowflakeIdComponent.getInstance().nextId();
            String jobOid = jobDTO.getOid();
            StringValueDO stringValueDO = new StringValueDO();
            stringValueDO.setObjbaseoid(new BigInteger(jobOid));
            stringValueDO.setObjbaseotype("ty.projectmng.job.CTyJob");
            BigInteger throughStatus = rtOutRuleMapper.selectOidByDisplayName("通过状态");
            stringValueDO.setAttrdefoid(throughStatus);
            stringValueDO.setAttrdefotype("ty.inteplm.attribute.CTyStringDef");
            stringValueDO.setCreatestamp(new Date());
            stringValueDO.setUpdatestamp(new Date());
            stringValueDO.setModifystamp(new Date());
            stringValueDO.setRefobjbaseotype("ty.zddw.kernel.CTyReferenceBase");
            stringValueDO.setOid(oid);
            stringValueDO.setValue("条件通过");
            stringValueDO.setValuex("条件通过");
            stringValueDOList.add(stringValueDO);
            updateJobThroughStatus(stringValueDOList,jobOid);
        }
        return jobDTOList;
    }

    //把字符串通过;分隔
    private static String[] getStringBeforeHyphen(String str) {
        String[] segments = str.split(";");
        return segments;
    }
    //把列表中的字符串去掉:后面
    private static String[] getStringBeforeColon(String[] segments) {


        for (int i = 0; i < segments.length; i++) {
            int hyphenIndex = -1;
            // 查找第一个"-"的位置
            hyphenIndex = segments[i].indexOf(":");
            if (hyphenIndex != -1) {
                segments[i] = segments[i].substring(0, hyphenIndex);
            }
        }
        return segments;
    }


    public void updateJobThroughStatus(List<StringValueDO> stringValueDOList, String jobOid)
            throws InterruptedException {
        if (CollUtil.isNotEmpty(stringValueDOList) && stringValueDOList.get(0).getAttrdefoid() != null) {
            //根据JobOid查询Job信息
            List<TyppmJobDTO> jobByOid = typpmJobService.getJobByOid(jobOid);
            if (CollUtil.isNotEmpty(jobByOid)) {
                TyppmJobDTO job = jobByOid.get(0);
                Map<String, List<String>> ibaAttribute = new HashMap<>();
                List<String> list = new ArrayList<>();
                list.add(stringValueDOList.get(0).getValue());
                ibaAttribute.put("ThroughStatus", list);
                job.setIbaAttribute(ibaAttribute);
                JobRemoteDTO jobRemoteDTO = (JobRemoteDTO) this.baseConvert.copyProperties(job, JobRemoteDTO.class);
                jobRemoteDTO.setTypeoid(Tools.toBigInteger(job.getTypeOID()));
                jobRemoteDTO.setTypeotype(job.getTypeOTYPE());
                //                String newExecutorId = "105";
                //                jobRemoteDTO.setExecutorOID(Tools.toBigInteger(newExecutorId));
                if (rtOutRuleMapper.selectIsHasDeliverRule(stringValueDOList.get(0).getObjbaseoid(),
                                                           rtOutRuleMapper.selectOidByDisplayName("通过状态"))
                        .isEmpty()) {
                    typlmAttributeValueMapper.batchInsertStringValue(stringValueDOList);
                } else {
                    if (ObjectUtil.isNotEmpty(jobRemoteDTO.getExecutorOID())) {

                        if (!jobRemoteDTO.getExecutorOID().equals(
                                new BigInteger("105")) && jobRemoteDTO.getPlanActiveName() != null) {
                            int maxRetry = 3;
                            int retryCount = 0;
                            while (retryCount < maxRetry) {
                                try {
                                    // 执行更新
                                    TyppmJobDTO typpmJobDTO = typpmJobService.updateJobAndCalculate(jobRemoteDTO);
                                    return;
                                } catch (DeadlockLoserDataAccessException e) { // 捕获死锁异常
                                    retryCount++;
                                    if (retryCount >= maxRetry) {
                                        throw new RuntimeException("更新失败", e);
                                    }
                                    // 重试前等待一小段时间（如100ms），降低再次冲突概率
                                    //Thread.sleep(100);
                                }
                            }
                        }
                    }

                }
            } else {
                if (rtOutRuleMapper.selectIsHasDeliverRule(stringValueDOList.get(0).getObjbaseoid(),
                                                           rtOutRuleMapper.selectOidByDisplayName("通过状态"))
                        .isEmpty()) {
                    typlmAttributeValueMapper.batchInsertStringValue(stringValueDOList);
                }
            }
            //                //删除过去的通过状态
            //                rtOutRuleMapper.batchDeleteIBAAttrForIntegerWithOid(stringValueDOList.get(0).getObjbaseoid());
            //                //批量保存
            //
        }
    }

}


